package cloud.health.common.file.application.impl;

import cloud.health.common.file.application.FileService;
import cloud.health.common.file.domain.AbstractFile;
import cloud.health.common.file.domain.BinaryFile;
import cloud.health.common.file.domain.Request;
import cloud.health.common.file.infrastructure.R;
import cn.hutool.http.HttpStatus;
import io.netty.buffer.Unpooled;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.regex.Pattern;

/**
 * 文件流上传
 */
@Slf4j
@Component
public class FileBinaryUploadServiceImpl implements FileService {

    private AbstractFile bf;

    @Override
    public boolean filter(Request request) {
        return request.getHttp().getMethod().toLowerCase().equals("post")
                && Pattern.compile("/api/v0/.*?/.*?").matcher(request.getHttp().getUri()).find()
                && !request.getHttp().getHeaders().getOrDefault("Content-Type", "").toString().contains("multipart/form-data;");
    }

    @Override
    public void handle(Request request) {
        if (bf == null) {
            bf = BinaryFile.create(request);
        }
        bf.writeAndFlush(request);
        if (request.completed()) {
            bf.close();
            R<AbstractFile> r;
            if (bf.isSuccess()) {
                r = R.success(bf);
            } else {
                r = R.fail(HttpStatus.HTTP_FORBIDDEN, bf.error());
            }
            request.getContext().writeAndFlush(Unpooled.wrappedBuffer(r.response()));
            bf = null;
        }
    }















    private static boolean isDataFormUpload(byte[] bytes) {
        for (int i = 0; i < bytes.length; i++) {
            if (i < 10 && (byte) 45 != bytes[i]) {
                return false;
            }
        }
        return true;
    }

    private static int startIn(byte[] bytes) {
        if (isDataFormUpload(bytes)) {
            return -1;
        }
        int index = 0;
        for (int i = 0; i < bytes.length; i++) {
            if (i > 0 && (byte) 10 == bytes[i] && (byte) 13 == bytes[i - 1]) {
                index = i;
                break;
            }
        }
        return index;
    }

    private static int endIn(byte[] bytes) {
        if (isDataFormUpload(bytes)) {
            return -1;
        }
        int index = 0;
        for (int i = bytes.length - 1; i > 0; i--) {
            if (i > 1 && (byte) 10 == bytes[i] && (byte) 13 == bytes[i - 1]) {
                index = i;
                break;
            }
        }
        return index;
    }

}
